home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- **
- ** $VER: ArgParse.rexx 1.06 by PATZ (31.10.95)
- **
- ** takes template & cmdline, returns line which caller has to INTERPRET
- **
- ** 1.00 : initial release
- ** 1.00->1.01 : added internal "PATZ/S" which lists all arguments
- ** 1.01->1.02 : added colored output to "PATZ/S"
- ** 1.02->1.03 : changed "PATZ/S" to "DEBUG_ARGPARSE/S"
- ** 1.03->1.04 : fixed severe bug in "/K": was using "k" as index
- ** 1.04->1.05 : added internal "QUIET_ARGPARSE/S" which disables erroroutput
- ** added support for "/N" (whole!), currently needs keyword!
- ** 1.05->1.06 : added underscore as first char to all variables - should give
- ** less collisions
- **
- ** Supported : /A,/K (NO combinations! eg /A/K), /S (-> 0/1), /N
- **
- ** Known Bugs: - cmdline cannot have "'" in it
- ** - template should not contain _#?/? words (not really a bug)
- **
- ******************************************************************************/
-
- PARSE ARG template,cmdline
-
- OPTIONS FAILAT 21
-
- /* template sample : "ACTION/A,DRIVE/A,FILE/A,TRACKS/K,VERBOSE/S,FORCE/S" */
-
- _err=0
- _errtext=""
- _argparse=""
- _internal_list=0
- _internal_quiet=0
- _ESC= '1b'x /* escape code */
-
- IF cmdline == "?" THEN DO
- ADDRESS command 'Echo "' || template || ': " NOLINE'
- PARSE PULL cmdline
- END
-
- /* checking quotes */
- _quotes=0
- _i=1
- DO FOREVER
- _i=POS('"',cmdline,_i)+1
- IF _i ~== 1 THEN
- _quotes=_quotes+1
- ELSE
- LEAVE
- END
- IF _quotes//2 == 1 THEN DO
- _errtext="PARSING ERROR: no matching quote"; _err=20
- SIGNAL CLEANUP
- END
-
- /* command line -> _argv & _argc */
- _argc=0
- _last=LENGTH(cmdline)
- _cl=cmdline || " "
-
- DO _i=1 TO _last
- _ch=SUBSTR(_cl,_i,1)
- IF _ch ~== " " THEN DO
- _argc=_argc+1
- _start=_i
- IF _ch == '"' THEN DO
- _i=POS('"',_cl,_start+1)+1
- _argv._argc=SUBSTR(_cl,_start,_i-_start)
- END
- ELSE DO
- _i=POS(" ",_cl,_start)
- _argv._argc='"' || SUBSTR(_cl,_start,_i-_start) || '"'
- END
- END
- END
-
- /* template -> A & K & S & N (& R) */
- _templateSPACE=TRANSLATE(template," ",",")
- _A=""; _K=""; _S=""; _N=""; _R=""
- DO _i=1 TO WORDS(_templateSPACE)
- _tp=WORD(_templateSPACE,_i); _len=LENGTH(_tp)-2; _type=RIGHT(_tp,2)
- SELECT
- WHEN _type == "/A" THEN
- _A=_A || " " || LEFT(_tp,_len)
- WHEN _type == "/K" THEN
- _K=_K || " " || LEFT(_tp,_len)
- WHEN _type == "/S" THEN
- _S=_S || " " || LEFT(_tp,_len)
- WHEN _type == "/N" THEN
- _N=_N || " " || LEFT(_tp,_len)
- OTHERWISE
- _R=_R || " " || _tp
- END
- END
- _A=STRIP(_A,'L'," "); _K=STRIP(_K,'L'," "); _S=STRIP(_S,'L'," "); _N=STRIP(_N,'L'," ")
- _R=STRIP(_R,'L'," ")
-
- /* /S */
- DO _i=1 TO WORDS(_S)+1 /* +1 is needed for internal /S */
- _var=UPPER(WORD(_S,_i))
- _line=_var || "=0" /* default value */
- DO _j=1 TO _argc
- IF UPPER(_argv._j) == '"DEBUG_ARGPARSE"' THEN DO /* internal */
- _internal_list=1
- _argv._j=""
- ITERATE
- END
- IF UPPER(_argv._j) == '"QUIET_ARGPARSE"' THEN DO /* internal */
- _internal_quiet=1
- _argv._j=""
- ITERATE
- END
- IF UPPER(_argv._j) == '"' || _var || '"' THEN DO
- _line=_var || "=1"
- _argv._j=""
- END
- END
- IF _line ~== "=0" THEN /* not internal */
- _argparse = _argparse || "; " || _line
- END
-
- /* /N, currently needs keyword! */
- DO _i=1 TO WORDS(_N)
- _var=UPPER(WORD(_N,_i))
- _line=_var || "='""""'"
- DO _j=1 TO _argc
- IF UPPER(_argv._j) == '"' || _var || '"' THEN DO
- _h=_j+1
- IF DATATYPE(STRIP(_argv._h,'B','"'),'W') ~== 1 THEN DO
- _errtext="ERROR: bad number"; _err=20
- SIGNAL CLEANUP
- END
- _line=_var || "=" || STRIP(_argv._h,'B','"')
- _argv._j=""
- _argv._h=""
- END
- END
- _argparse = _argparse || "; " || _line
- END
-
- /* /K */
- DO _i=1 TO WORDS(_K)
- _var=UPPER(WORD(_K,_i))
- _line=_var || "='""""'"
- DO _j=1 TO _argc
- IF UPPER(_argv._j) == '"' || _var || '"' THEN DO
- _h=_j+1
- _line=_var || "='" || _argv._h || "'"
- _argv._j=""
- _argv._h=""
- END
- END
- _argparse = _argparse || "; " || _line
- END
-
- /* /A */
- DO _i=1 TO WORDS(_A)
- _var=TRANSLATE(UPPER(WORD(_A,_i)))
- _line=_var || "='""""'"
- DO _j=1 TO _argc
- IF UPPER(_argv._j) == '"' || _var || '"' THEN DO
- _k=_j+1
- _line=_var || "='" || _argv._k || "'"
- _argv._j=""
- _argv._k=""
- END
- END
- INTERPRET _line /* MUST remain here! */
- IF RIGHT(_line,4) ~== "'""""'" THEN
- _argparse = _argparse || "; " || _line
- END
-
- /* fill empty /A's */
- _start=1
- DO _i=1 TO WORDS(_A)
- _var=WORD(_A,_i)
- _line="_value=" || _var
- INTERPRET _line /* MUST remain here! */
- IF _value ~== '""' THEN
- ITERATE
- DO WHILE (_argv._start="") & (_start<=_argc)
- _start=_start+1
- END
- IF _start>_argc THEN DO
- _errtext="required argument missing"; _err=20
- SIGNAL CLEANUP
- END
- _line=_var || "='" || _argv._start || "'"
- _argv._start=""
- _argparse = _argparse || "; " || _line
- END
-
- DO _i=1 TO _argc
- IF _argv._i ~== "" THEN DO
- _errtext="wrong number of arguments"; _err=20
- END
- END
-
- CLEANUP:
- /* internal */
- IF _internal_list == 1 THEN DO
- SAY "Internal 'ArgParse' output:"
- _internal_ap=STRIP(_argparse,'L',"; ")
- INTERPRET _internal_ap
- DO _i=1 TO WORDS(_templateSPACE)
- _line=WORD(_templateSPACE,_i)
- _line2=LEFT(_line,LENGTH(_line)-2)
- _line3='SAY " ' || LEFT(_line2,10," ") || '=' || _ESC || '[32m"' || _line2 || '"' || _ESC || '[0m"'
- INTERPRET _line3
- END
- SAY ""
- END
-
- IF _err ~== 0 THEN DO
- IF _internal_quiet ~== 1 THEN
- SAY _errtext
- EXIT _err
- END
-
- RETURN STRIP(_argparse,'L',"; ")
-
-